// 一，泛型对函数的应用
// attentions: 下面的方式 都是一个意思
// 泛型只有在调用的时候才知道 具体的类型 ，实现的时候不知道， 下面仅仅是实现，未调用

// 1.普通函数种的使用
const getArray1 = <T, U>(value: T, time: U): Array<T | U> => {
  return [value, time];
};

// 2.函数类型约束中的使用
let getArray2: <T>(arg: T, time: number) => T[];
getArray2 = (arg, time) => {
  return [arg];
};

// 3.类型别名中的使用
type GetArray1 = <T>(arg: T, time: number) => T[];

// 4.接口种使用泛型
interface GetArray2 {
  <T>(arg: T, time: number): T[];
}

// 二，泛型的约束
//1.
interface Info {
  length: number;
}
// 要求传递 的 参数必须符合这个接口的类型 ，在这里意思就是要有length 属性，
const getArray = <T extends Info>(args: T, time): T[] => {
  return new Array(time).fill(args);
};

// 2.泛型约束 参数
const getProps = <T, K extends keyof T>(obj: T, prop: K) => {
  return obj[prop];
};
const objs = {
  a: 'a',
  b: 'b',
};
getProps(objs, 'a');
// getProps(objs, 'c');// 这里就报错了
